package com.oanda.blackberry.view;

import java.util.Timer;
import java.util.TimerTask;

import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.decor.BackgroundFactory;

import com.oanda.blackberry.OandaBlackBerryApplication;
import com.oanda.blackberry.net.ConnectionManager;
import com.oanda.blackberry.restapi.Quote;
import com.oanda.blackberry.restapi.Rate;
import com.oanda.blackberry.ui.OandaMainScreen;
import com.oanda.blackberry.util.AbstractViewPanel;
import com.oanda.blackberry.util.DefaultController;
import com.oanda.blackberry.util.Model;
import com.oanda.blackberry.util.PropertyChangeEvent;
import com.oanda.blackberry.util.log.Logger;

public class RatesView extends OandaMainScreen implements AbstractViewPanel {
    DefaultController controller;
    Timer updateTimer = new Timer();

    TimerTask updateTask = new TimerTask() {
        public synchronized void run() {
            if (OandaBlackBerryApplication.isInForeground) {
                RatesView.this.updateQuote();
            } else {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
    };

    Timer allQuoteTimer = new Timer();
    TimerTask updateAllQuotes = new TimerTask() {
        public void run() {
            RatesView.this.updateAllQuotes();
        }
    };

    private long UPDATE_TIME = 5000L;
    RatesListField list;
    VerticalFieldManager v1 = new VerticalFieldManager();
    VerticalFieldManager v2 = new VerticalFieldManager();
    VerticalFieldManager v3 = new VerticalFieldManager();

    VerticalFieldManager listManager = new VerticalFieldManager();
    Rate rateTemp;
    String selectedQuotesTemp = null;

    MenuItem sell = new MenuItem("Sell", 10, 995) {
        public void run() {
            RatesView.this.controller.sell(RatesView.this.list.getQuoteSelected());
        }
    };

    MenuItem buy = new MenuItem("Buy", 10, 996) {
        public void run() {
            Quote q = null;
            if (RatesView.this.list != null) {
                q = RatesView.this.list.getQuoteSelected();
            }
            RatesView.this.controller.buy(q);
        }
    };

    MenuItem trades = new MenuItem("Trades", 10, 997) {
        public void run() {
            RatesView.this.controller.propertyChange(new PropertyChangeEvent(this,
                    "requestShowTradesView", RatesView.this.controller, RatesView.this.controller));
        }
    };

    MenuItem orders = new MenuItem("Orders", 10, 998) {
        public void run() {
            RatesView.this.controller.propertyChange(new PropertyChangeEvent(this,
                    "requestShowOrdersView", RatesView.this.controller, RatesView.this.controller));
        }
    };

    MenuItem positions = new MenuItem("Positions", 10, 999) {
        public void run() {
            RatesView.this.controller.propertyChange(new PropertyChangeEvent(this,
                    "requestShowPositionsView", RatesView.this.controller,
                    RatesView.this.controller));
        }
    };

    MenuItem accounts = new MenuItem("Accounts", 10, 999) {
        public void run() {
            RatesView.this.controller.propertyChange(new PropertyChangeEvent(this,
                    "requestShowAccountsView", null, RatesView.this.controller));
        }
    };

    MenuItem showListSymbolsScreenMenuItem = new MenuItem("Edit Rates", 1000, 1000) {
        public void run() {
            RatesView.this.controller.propertyChange(new PropertyChangeEvent(this,
                    "showListSymbols", RatesView.this.controller, RatesView.this.controller));
        }
    };

    MenuItem historyCs = new MenuItem("History(Custom sec)", 10, 1001) {
        public void run() {
            String[] choices = { "1", "2", "3", "5", "10", "15", "30", "60" };
            int[] scales = { 1, 2, 3, 5, 10, 15, 30, 60 };
            int g = Dialog.ask("Select a granularity in seconds", choices, scales, 10);
            String[] choices2 = { "1", "3", "5", "10", "15", "20", "30", "50", "100", "200" };
            int[] scales2 = { 1, 3, 5, 10, 15, 20, 30, 50, 100, 200 };

            int p = Dialog.ask("Select a scale points", choices2, scales2, 10);

            RatesView.this.controller.history(RatesView.this.list.getQuoteSelected(), g, p);
        }
    };

    MenuItem history = new MenuItem("Charts", 10, 1001) {
        public void run() {
            String[] choices = { "5 sec", "30 sec", "1 min", "5 min", "15 min", "1 hour", "1 day" };
            int[] scales = { 5, 30, 60, 300, 150, 3600, 86400 };

            Model.getModel();
            int p = Model.getHistoryPoints(Model.getModel().getHistoryChartTypeIndex());

            int g = 0;
            String title = Model.getModel().getSettings().getHistoryTimeInterval();
            if (title.indexOf(choices[0]) > -1)
                g = scales[0];
            if (title.indexOf(choices[1]) > -1)
                g = scales[1];
            if (title.indexOf(choices[2]) > -1)
                g = scales[2];
            if (title.indexOf(choices[3]) > -1)
                g = scales[3];
            if (title.indexOf(choices[4]) > -1)
                g = scales[4];
            if (title.indexOf(choices[5]) > -1)
                g = scales[5];
            if (title.indexOf(choices[6]) > -1)
                g = scales[6];

            RatesView.this.controller
                    .propertyChange(new PropertyChangeEvent(this, "requestShowHistoryView",
                            RatesView.this.controller, RatesView.this.controller));
            RatesView.this.controller.history(RatesView.this.list.getQuoteSelected(), g, p);
        }
    };

    MenuItem history5s = new MenuItem("History(5 sec)", 10, 1001) {
        public void run() {
            RatesView.this.controller.history(RatesView.this.list.getQuoteSelected(), 5, 10);
        }
    };

    MenuItem history30s = new MenuItem("History(30 sec)", 10, 1002) {
        public void run() {
            RatesView.this.controller.history(RatesView.this.list.getQuoteSelected(), 30, 10);
        }
    };

    MenuItem history1m = new MenuItem("History(1 min)", 10, 1003) {
        public void run() {
            RatesView.this.controller.history(RatesView.this.list.getQuoteSelected(), 60, 10);
        }
    };

    MenuItem history5m = new MenuItem("History(5 min)", 10, 1004) {
        public void run() {
            RatesView.this.controller.history(RatesView.this.list.getQuoteSelected(), 300, 10);
        }
    };

    MenuItem history15m = new MenuItem("History(15 min)", 10, 1005) {
        public void run() {
            RatesView.this.controller.history(RatesView.this.list.getQuoteSelected(), 900, 10);
        }
    };

    MenuItem history1h = new MenuItem("History(1 hour)", 10, 1006) {
        public void run() {
            RatesView.this.controller.history(RatesView.this.list.getQuoteSelected(), 3600, 10);
        }
    };

    MenuItem history24h = new MenuItem("History(1 day)", 10, 1007) {
        public void run() {
            RatesView.this.controller.history(RatesView.this.list.getQuoteSelected(), 86400, 10);
        }
    };

    MenuItem logoutMenuItem = new MenuItem("Log out", 1000, 20000) {
        public void run() {
            if (4 == Dialog.ask(3, "Are you sure you want to log out?")) {
                RatesView.this.controller.logout(Model.getModel().getSessionToken());
            }
        }
    };

    MenuItem optionsMenuItem = new MenuItem("Options", 1000, 20001) {
        public void run() {
            RatesView.this.controller.showOptions();
        }
    };

    MenuItem helpMenuItem = new MenuItem("Contact", 1000, 20002) {
        public void run() {
            RatesView.this.controller.help();
        }
    };

    MenuItem aboutMenuItem = new MenuItem("About", 1000, 20003) {
        public void run() {
            RatesView.this.controller.about();
        }
    };

    MenuItem debugMenu = new MenuItem("Debug Menu", 1000, 20004) {
        public void run() {
            RatesView.this.controller.propertyChange(new PropertyChangeEvent(this, "showMenuView",
                    RatesView.this.controller, RatesView.this.controller));
        }
    };

    public void notifyTimerTask() {
        if (this.updateTask != null) {
            synchronized (this.updateTask) {
                this.updateTask.notifyAll();
            }
        }
    }

    public RatesView(DefaultController controller) {
        this.controller = controller;
        getMainManager().setBackground(BackgroundFactory.createSolidBackground(4473924));

        updateTitle();

        add(this.listManager);
    }

    protected void onUiEngineAttached(boolean attached) {
        if (attached) {
            this.controller.propertyChange(new PropertyChangeEvent(null, "mainMenuShown", null,
                    null));

            showThrobberPlain();

            updateTitle();

            if (this.updateTimer == null) {
                this.updateTimer = new Timer();
            }

            if (this.updateTask == null)
                this.updateTask = new TimerTask() {
                    public void run() {
                        RatesView.this.updateQuote();
                    }
                };
            this.updateTimer.schedule(this.updateTask, 0L, this.UPDATE_TIME);
        } else {
            Logger.log("rates on UI EngineAttached cancelling");
            if (this.updateTask != null) {
                this.updateTask.cancel();
                this.updateTask = null;
            }
            if (this.updateTimer != null) {
                Logger.log("cancelling");
                this.updateTimer.cancel();
                this.updateTimer = null;
                Logger.log("Canceled");
            }
        }
    }

    private void setRates(final Rate rate) {
        if ((rate != null) && (rate.getQuotes() != null)) {
            if ((this.rateTemp != null) && (this.selectedQuotesTemp != null)
                    && (this.selectedQuotesTemp.equals(Model.getModel().getRateSymbolsSelected()))) {
                for (int j = 0; j < rate.getQuotes().length; j++) {
                    for (int i = 0; i < this.rateTemp.getQuotes().length; i++) {
                        if ((this.list == null)
                                || (!this.rateTemp.getQuotes()[i].getSymbol().equals(
                                        rate.getQuotes()[j].getSymbol()))
                                || (Rate.isQuotesEquals(this.rateTemp.getQuotes()[i],
                                        rate.getQuotes()[j]))) {
                            continue;
                        }
                        this.list.setQuote(rate.getQuotes()[j]);
                    }
                }
            } else {

                UiApplication.getUiApplication().invokeLater(new Runnable() {
                    private final Rate _rate = rate;

                    public void run() {
                        RatesView.this.v1.deleteAll();
                        RatesView.this.v2.deleteAll();
                        RatesView.this.v3.deleteAll();
                        RatesView.this.listManager.deleteAll();

                        if ((this._rate.getQuotes() != null) && (this._rate.getQuotes().length > 0)) {
                            RatesView.this.list = new RatesListField(this._rate);
                            RatesView.this.listManager.add(RatesView.this.list.getList());
                        }
                    }
                });
                this.selectedQuotesTemp = Model.getModel().getRateSymbolsSelected();
                this.rateTemp = rate;
            }
        }

        hideThrobber();
        invalidate();
    }

    public void modelPropertyChange(PropertyChangeEvent evt) {
        if ((evt.getPropertyName().equals("setActiveAccount")) && (evt.getNewValue() != null)
                && ((evt.getNewValue() instanceof String))) {
            updateTitle();
        }

        if (evt.getPropertyName().equals("removeRateQuoteStatus")) {
            removeStatusField();
        } else if (evt.getPropertyName().equals("setRateQuoteStatus")) {
            setStatusField((String) evt.getNewValue());
        } else if (evt.getPropertyName().equals("setRateQuote")) {
            setRates((Rate) evt.getNewValue());
        } else if (evt.getPropertyName().equals("showRatesView")) {
            this.controller.pushScreen(this);
        } else if (evt.getPropertyName().equals("hideRatesView"))
            this.controller.popScreen(this);
        else if ((evt.getPropertyName().equals("RatesException")) && (evt.getNewValue() != null)
                && ((evt.getNewValue() instanceof String)) && (this.rateTemp == null)) {
            diplayError((String) evt.getNewValue(), 5000, "retrying...");
        }
    }

    private void updateQuote() {
        if (UiApplication.getUiApplication().getActiveScreen().equals(this)) {
            updateTitle();
            this.controller.updateQuote();
            this.controller.turnLED();
            this.controller.turnOnBacklight();
        }
    }

    private void updateAllQuotes() {
        if (UiApplication.getUiApplication().getActiveScreen().equals(this))
            ;
    }

    protected void makeMenu(Menu menu, int instance) {
        if (this.rateTemp != null) {
            menu.add(this.trades);
            menu.add(this.orders);
            menu.add(this.positions);
            menu.addSeparator();
            menu.add(this.buy);
            menu.add(this.sell);
            menu.addSeparator();
        }
        menu.add(this.showListSymbolsScreenMenuItem);

        if (this.rateTemp != null) {
            menu.add(this.history);
            menu.addSeparator();
        }

        menu.add(this.accounts);
        menu.addSeparator();
        menu.add(this.logoutMenuItem);
        menu.addSeparator();
        menu.add(this.optionsMenuItem);
        menu.add(this.helpMenuItem);
    }

    private void onExit() {
        if (this.updateTimer != null) {
            this.updateTask.cancel();
            this.updateTimer.cancel();
            this.updateTimer = null;
            this.updateTask = null;
        }

        if (this.allQuoteTimer != null) {
            this.updateAllQuotes.cancel();
            this.allQuoteTimer.cancel();
            this.updateAllQuotes = null;
            this.allQuoteTimer = null;
        }

        Logger.log("onClose");

        Model.getModel().getRate();
        Rate.setSince(0L);

        Model.getModel().getSettings().commit();

        this.controller.exit();
    }

    public boolean onClose() {
        UiApplication.getUiApplication().requestBackground();

        return true;
    }

    private void updateTitle() {
        Runnable r = new Runnable() {
            public void run() {
                String server = ConnectionManager.getUrlFriendlyName();
                String accountId = Model.getModel().getActiveAccountId();

                String newTitle = "Rates (" + server + (accountId != null ? " - " + accountId : "")
                        + ")";

                RatesView.this.updateTitle(newTitle);
            }
        };
        this.controller.invokeLater(r);
    }
}
